package com.atguigu.config;

import com.atguigu.bean.Car;
import com.atguigu.bean.Color;
import com.atguigu.bean.Dog;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@ComponentScan(value = {"com.atguigu.bean"})
//@Import(value = {Color.class})
public class MainConfigLifeCycle {

    /**
     * bean的生命周期：
     * 		bean创建---初始化----销毁的过程
     * 容器管理bean的生命周期；
     * 我们可以自定义初始化和销毁方法；容器在创建bean的过程中，当进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
     *
     * 构造（对象创建）
     * 		单实例：在容器启动的时候创建对象
     * 		多实例：在每次获取的时候创建对象
     *
     * 给bean进行属性赋值
     *
     * BeanPostProcessor.postProcessBeforeInitialization (在初始化方法执行之前进行后置处理工作)
     * 初始化：对象创建完成，并赋值好，调用初始化方法。。。
     * BeanPostProcessor.postProcessAfterInitialization  (在初始化方法执行之后进行后置处理工作)
     *
     * 销毁：
     * 		单实例：容器关闭的时候
     * 		多实例：容器不会管理这个bean；容器不会调用销毁方法；
     *
     *
     * 遍历得到容器中所有的BeanPostProcessor；挨个执行postProcessBeforeInitialization
     * 一但返回null，跳出for循环，不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
     *
     * BeanPostProcessor原理
     * populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
     * initializeBean
     * {
     *   invokeAwareMethods
     *   applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
     *   invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
     *   applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
     * }
     *
     *
     *
     * 指定初始化和销毁方法有如下方式；
     * 1）、	通过@Bean指定init-method和destroy-method；【见Car类】
     *
     * 2）、通过让Bean实现InitializingBean（定义初始化逻辑），
     * 				    DisposableBean（定义销毁逻辑）; 【见Cat类】
     *
     * 3）、可以使用JSR250；
     * 		@PostConstruct：在bean创建完成并且属性赋值完成；来执行初始化方法
     * 		@PreDestroy：在容器销毁bean之前通知我们进行清理工作 【见Dog类】
     *
     * 4）、BeanPostProcessor【interface】：bean的后置处理器；
     * 		在bean初始化前后进行一些处理工作；
     * 		postProcessBeforeInitialization:在初始化方法之前工作
     * 		postProcessAfterInitialization:在初始化方法之后工作
     *
     * Spring底层对 BeanPostProcessor 的使用；
     * 		bean赋值，注入其他组件，@Autowired，生命周期注解功能，@Async,xxx BeanPostProcessor;
     *
     * @author lfy
     *
     */
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Car car(){
        return new Car();
    }

    // 将后置处理器加入到容器中
    @Bean
    public MyBeanPostProcessor myBeanPostProcessor(){
        return new MyBeanPostProcessor();
    }
    //
    //@Bean
    //public Dog dog(){
    //    return new Dog();
    //}
}
